//#include "tim.h"
#include "gpio.h"
#include "main.h"
#include "tim.h"
typedef struct w1_gpio_s
{
	GPIO_TypeDef   *group;
	uint16_t        pin;
}w1_gpio_t;

static w1_gpio_t W1Dat=
{
		.group=GPIOA,
		.pin=GPIO_PIN_12,
};

#define W1DQ_Input() \
{  \
	GPIO_InitTypeDef GPIO_Initstruct={0};  \
	GPIO_Initstruct.Pin=W1Dat.pin;  \
	GPIO_Initstruct.Mode=GPIO_MODE_INPUT;  \
	GPIO_Initstruct.Pull=GPIO_PULLUP;  \
	GPIO_Initstruct.Speed=GPIO_SPEED_FREQ_HIGH;  \
	HAL_GPIO_Init(W1Dat.group,&GPIO_Initstruct); \
}

#define W1DQ_Output() \
{ \
	GPIO_InitTypeDef GPIO_Initstruct={0}; \
	GPIO_Initstruct.Pin=W1Dat.pin; \
	GPIO_Initstruct.Mode=GPIO_MODE_OUTPUT_PP; \
	GPIO_Initstruct.Pull=GPIO_NOPULL; \
	GPIO_Initstruct.Speed=GPIO_SPEED_FREQ_HIGH; \
	HAL_GPIO_Init(W1Dat.group,&GPIO_Initstruct); \
}

#define W1DQ_Write(x)  HAL_GPIO_WritePin(W1Dat.group,W1Dat.pin, \
							x==0?GPIO_PIN_RESET:GPIO_PIN_SET)

#define W1DQ_Read()      HAL_GPIO_ReadPin(W1Dat.group,W1Dat.pin)

uint8_t DS18B20_Reset(void)
{
	uint8_t    rv=0;
	uint8_t    retry;

	W1DQ_Output();
	W1DQ_Write(1);
	delay_us(2);

	W1DQ_Write(0);
	delay_us(480);

	W1DQ_Write(1);
	delay_us(60);

	while(W1DQ_Read()&&retry<240)
	{
		retry++;
		delay_us(1);
	}

	if(retry>=240)
	rv=1;

	delay_us(240);

	W1DQ_Output();
	W1DQ_Write(1);
	delay_us(240);

	return rv;
}

void DS18B20_WriteByte(uint8_t byte)
{
	uint8_t i=0;
	W1DQ_Output();

	for(i=0;i<8;i++)
	{
		W1DQ_Write(0);
		delay_us(10);

		if(byte&0x1)
			W1DQ_Write(1);
		else
			W1DQ_Write(0);

		delay_us(60);

		W1DQ_Write(1);
		delay_us(2);

		byte>>=1;
	}
}

uint8_t DS18B20_ReadByte(void)
{
	uint8_t   i=0;
	uint8_t   byte=0;

	for(i=0;i<8;i++)
	{
		W1DQ_Output()
		W1DQ_Write(0);
		delay_us(2);
		W1DQ_Write(1);
		delay_us(2);

		W1DQ_Input();

		if(W1DQ_Read())
		{
			byte |=1<<i;
		}
		delay_us(60);

		W1DQ_Output();
		W1DQ_Write(1);
		delay_us(2);

	}
	return byte;
}

static inline int DS18B20_Start_Convert(void)
{
	if(0!=DS18B20_Reset())
		return -1;
	DS18B20_WriteByte(0xCC);
	DS18B20_WriteByte(0x44);

	return 0;
}

static inline int DS18B20_Start_Read(uint8_t *buf,int bytes)
{
	if(0!=DS18B20_Reset())
	{
		return -1;
	}
		DS18B20_WriteByte(0xCC);
		DS18B20_WriteByte(0xBE);

		buf[0]=DS18B20_ReadByte();
		buf[1]=DS18B20_ReadByte();

		return 0;
}

int DS18B20_SampleData(float *temperature)
{
	uint8_t 	byte[2];
	uint8_t 	sign;
	uint16_t 	temp;

	if(!temperature)
		return -1;

	if(0!=DS18B20_Start_Convert())
		return -2;

	if(0!=DS18B20_Start_Read(byte, 2))
		return -3;

	if(byte[1]>0x7)
	{
		temp =~(byte[1]<<8|byte[0])+1;
		sign=0;
	}

	else
	{
		sign=1;
		temp =byte[1]<<8 | byte[0];
	}
	*temperature=(temp>>4)+(temp&0xF)*0.0625;
	if(!sign)
	{
		*temperature=-*temperature;
	}
	return 0;
}




